<script setup lang="ts">
import useWebSocket from "@/utils/http/websocket";
import VueCodemirror from "codemirror-editor-vue3";
import { onMounted, ref, watch } from "vue";
import { Terminal } from "@xterm/xterm";
import "@xterm/xterm/css/xterm.css";
import { FitAddon } from "@xterm/addon-fit";
import { CanvasAddon } from "@xterm/addon-canvas";

type Prop = {
  url?: string;
  namespace?: string;
  pod?: string;
  container?: string;
};
const props = defineProps<Prop>();
const {
  wsClose,
  wsConnect,
  wsLastMsg,
  wsMessages,
  wsSend,
  wsStatus,
  wsMsgWatch
} = useWebSocket();

const logMsg = ref("");

const reconnect = (url?: string) => {
  wsClose();
  if (url) {
    wsConnect(url);
  }
};

const onMessageReceived = (msg: any) => {
  // logMsg.value += msg;
  if (`${msg}` === "pong") {
    return;
  }
  terminalEngine.value.write(msg);
};
wsMsgWatch(onMessageReceived);

const terminalEngine = ref();
const terminal = ref();
const inputCommand = ref("");
const initTerminal = () => {
  terminalEngine.value = new Terminal({
    rows: 200, //行数
    cols: 120,
    convertEol: true, //启用时，光标将设置为下一行的开头
    scrollback: 10, //终端中的回滚量
    disableStdin: false, //是否应禁用输入
    cursorStyle: "underline", //光标样式
    cursorBlink: true, //光标闪烁
    theme: {
      foreground: "white", //字体
      background: "#060101", //背景色
      cursor: "help" //设置光标
    }
  });
  terminalEngine.value.open(terminal.value);

  // 终端适应父元素大小;
  const fitAddon = new FitAddon();
  terminalEngine.value.loadAddon(fitAddon);
  fitAddon.fit();

  //监听窗口大小变化
  window.addEventListener("resize", () => {
    fitAddon.fit();
  });

  // canvas
  terminalEngine.value.loadAddon(new CanvasAddon());

  //获取终端的焦点
  terminalEngine.value.focus();

  terminalEngine.value.write(
    `Welcome to the terminal \
    \n# Namespace: ${props.namespace}\
    \n# Pod: ${props.pod}\
    \n# Container: ${props.container} \
    \n\n`
  );

  terminalEngine.value.onKey(e => {
    console.log(e);
    // is turndown
    if (e.key === "\r" || e.key === "\n") {
      // send
      terminalEngine.value.write("\n");
      wsSend({ cmd: inputCommand.value + "\n" });
      inputCommand.value = "";
    } else if (
      e.domEvent.ctrlKey &&
      `${e.domEvent.key}`.toLowerCase() === "c"
    ) {
      // cancel
      terminalEngine.value.write("^C\n# ");
      inputCommand.value = "";
    } else {
      inputCommand.value += e.key;
      terminalEngine.value.write(e.key);
    }
  });
};

onMounted(() => {
  reconnect(props.url);
  initTerminal();
});

watch(
  () => props.url,
  (val, oldVal) => {
    if (val !== oldVal) {
      reconnect(val);
    }
  }
);

defineExpose({
  close: wsClose
});
</script>

<template>
  <div v-loading="wsStatus !== 'connected'" class="terminal-wrapper">
    <div ref="terminal" />
  </div>
</template>
<style lang="scss" scoped>
.terminal-wrapper {
  height: 100%;
  width: 100%;
  // overflow: auto;
}
</style>
